package cn.hznc.controller.service.order;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.constant.CommonConstant;
import cn.hznc.constant.WarehouseConstant;
import cn.hznc.controller.service.QuerySqlServerService;
import cn.hznc.controller.service.inventory.InventoryLocationService;
import cn.hznc.controller.service.order.logic.OrderDo;
import cn.hznc.controller.service.production.ProductionManageService;
import cn.hznc.controller.service.program.SubProgramManageService;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.inventory.InBoundOrOutBoundTimeReq;
import cn.hznc.domain.request.order.AbutmentOrderReq;
import cn.hznc.dto.AbutmentInboundExport;
import cn.hznc.dto.AbutmentOutboundExport;
import cn.hznc.excel.*;
import cn.hznc.exception.ToolLifeCycleEx;
import cn.hznc.exception.ToolLifeCycleException;
import cn.hznc.mapper.*;
import cn.hznc.repository.*;
import cn.hznc.controller.task.InventoryTask;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.AbutmentStockVo;
import cn.hznc.vo.ImportToolForkInfoVo;
import cn.hznc.vo.LocationNumberVo;
import com.alibaba.excel.EasyExcel;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author：Administrator
 * @Date：2023/7/25 17:17
 */
@Service
@Slf4j
public class AbutmentService{

    @Autowired
    private OrderManageService orderManageService;

    @Autowired
    private ProductionManageService productionManageService;

    @Resource
    private ProductionMapper productionMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ProcessMapper processMapper;

    @Resource
    private ProductionProcessMapper productionProcessMapper;

    @Resource
    private ProcessCraftMapper processCraftMapper;

    @Resource
    private ProductionBomMapper productionBomMapper;

    @Resource
    private AbutmentEntryAndExitMapper abutmentEntryAndExitMapper;

    @Resource
    private ProgramRepository programRepository;

    @Resource
    private AbutmentEntryExitRepository abutmentEntryExitRepository;

    @Autowired
    private SubProgramManageService subProgramManageService;

    @Resource
    private QuerySqlServerService querySqlServerService;

    @Resource
    private WarehouseRespository warehouseRespository;

    @Resource
    private ToolForkInfoMapper toolForkInfoMapper;

    @Resource
    private ToolConnectMapper toolConnectMapper;
    @Resource
    private InventoryLocationService inventoryLocationService;

    @Resource
    private InventoryLocationRespository inventoryLocationRespository;

    @Resource
    private InventoryTask inventoryTask;

    @Resource
    private SubProgramMapper subProgramMapper;

    private static final Integer INBOUND_TYPE = 1;

    private static final Integer OUTBOUND_TYPE = 2;


    private static final List<String> keyWordList = new ArrayList<>();

    private static final String CONNECT_CRAFT_NAME1 = "数控车削";
    private static final String CONNECT_CRAFT_NAME2 = "精车车削";
    private static final String CONNECT_CRAFT_NAME3 = "三四轴铣削加工中心";
    private static final String CONNECT_CRAFT_NAME4 = "五轴铣削加工中心";

    static {
        keyWordList.add(CONNECT_CRAFT_NAME1);
        keyWordList.add(CONNECT_CRAFT_NAME2);
        keyWordList.add(CONNECT_CRAFT_NAME3);
        keyWordList.add(CONNECT_CRAFT_NAME4);
    }

    public List<String> abutmentData(AbutmentOrderReq abutmentOrderReq){
        List<Map<String , String>> materialNos = orderManageService.abutmentOrder(abutmentOrderReq);
        if(CollectionUtil.isEmpty(materialNos)){
            return new ArrayList<>();
        }
        productionManageService.abutmentProductionReload1(materialNos);
        subProgramManageService.abutmentSubProgramReload1(materialNos);
        List<String> partnoList = new ArrayList<>();
        materialNos.forEach(stringStringMap -> {
            partnoList.add(stringStringMap.get("materialNo"));
        });
        return partnoList;
    }

//    public void abutmentDataReload(AbutmentOrderReloadReq abutmentOrderReq){
//        List<Map<String , String>> materialNos = orderManageService.abutmentOrder(abutmentOrderReq);
//        if(CollectionUtil.isEmpty(materialNos)){
//            return;
//        }
//        productionManageService.abutmentProductionReload1(materialNos);
//        subProgramManageService.abutmentSubProgramReload1(materialNos);
//    }



    /**
     * 对接数据关联关系
     */
    @Transactional
    public Boolean abutmentDataConnect(){
        QueryWrapper<ProductionEntity> productionWrapper = new QueryWrapper<>();
        //查询状态为未完成的产品
        productionWrapper.eq("status" , 0);
        List<ProductionEntity> productionEntities = productionMapper.selectList(productionWrapper);
        dataConnect(productionEntities);
        return Boolean.TRUE;
    }

    public void dataConnect(List<ProductionEntity> productionEntities) {
        List<ProductionProcessEntity> addProductionProcessConnect = new ArrayList<>();
        List<ProcessEntity> updateProcessConnectList = new ArrayList<>();
        List<OrderEntity> updateOrderList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(productionEntities)){
            productionEntities
                    .stream()
                    //.filter(productionEntity -> StringUtil.isNotEmpty(productionEntity.getFigureNo()))
                    .forEach(productionEntity -> {
                List<OrderEntity> connectOrders = new ArrayList<>();
                //查询对应工单并设置对应状态位
                QueryWrapper<OrderEntity> orderWrapper = new QueryWrapper<>();
                orderWrapper.eq("material_no" , productionEntity.getMaterialNo());
                List<OrderEntity> orderEntities = orderMapper.selectList(orderWrapper);
                orderEntities.forEach(orderEntity -> {
                    orderEntity.setStatus(CommonConstant.ORDER_PRODUCTION_CONNECT_NOT_DONE);
                    orderEntity.setFigureNo(productionEntity.getFigureNo());
                    orderEntity.setFigureNoImage(productionEntity.getImage());
                    orderEntity.setProductionNum(productionEntity.getProductionNum());
                    orderEntity.setMaterialNo(productionEntity.getMaterialNo());
                    orderEntity.setProductionName(productionEntity.getName());
                    orderEntity.setHeavy(productionEntity.getHeavy());
                    connectOrders.add(orderEntity);
                    updateOrderList.add(orderEntity);
                });

                //查询物料信息
                QueryWrapper<ProductionBomEntity> bomWrapper = new QueryWrapper<>();
                bomWrapper.eq("figure_no" , productionEntity.getMaterialNo());
                List<ProductionBomEntity> connectBom =  productionBomMapper.selectList(bomWrapper);

                //查询对应工艺
                QueryWrapper<ProcessEntity> wrapper = new QueryWrapper<>();
                wrapper.eq("process_num" , productionEntity.getMaterialNo());
                ProcessEntity connectProcess = processMapper.selectOne(wrapper);
                //添加工艺和产品的关联关系
                if(ObjectUtil.isNotNull(connectProcess)){
                    if(productionEntity.getProductionProcessConnectStatus() == 0){
                        ProductionProcessEntity productionProcessEntity = new ProductionProcessEntity();
                        productionProcessEntity.setProductionId(productionEntity.getId());
                        productionProcessEntity.setProcessId(connectProcess.getId());
                        productionProcessEntity.setIsUsing(1);
                        addProductionProcessConnect.add(productionProcessEntity);
                        //设置产品的工艺关联状态为已关联
                        productionEntity.setProductionProcessConnectStatus(1);
                    }
                    //查询对应程序并关联到对应子工序(内联查询，主程序有对应子程序则能查到， 主程序无子程序则查不到)
//                    if(productionEntity.getProcessStatus() == 1){
//                        return;
//                    }
                    String materialNo = productionEntity.getMaterialNo().trim();
                    ProgramEntity connectProgram = programRepository.selectByProgramNum(materialNo);
                    //查询对应工序的子工序
                    QueryWrapper<ProcessCraftEntity> processCraftWrapper = new QueryWrapper<>();
                    processCraftWrapper.eq("process_code" , connectProcess.getCode());
                    List<ProcessCraftEntity> connectCraftEntities = processCraftMapper.selectList(processCraftWrapper);
                    if(ObjectUtil.isNotNull(connectProgram)){
                        //查询对应工序的子工序
//                        QueryWrapper<ProcessCraftEntity> processCraftWrapper = new QueryWrapper<>();
//                        processCraftWrapper.eq("process_code" , connectProcess.getCode());
//                        List<ProcessCraftEntity> connectCraftEntities = processCraftMapper.selectList(processCraftWrapper);
                        //查询对应子工序不为空，通过关键字过滤需要关联程序的子工序
                        if(CollectionUtil.isNotEmpty(connectCraftEntities)){
                            List<ProcessCraftEntity> updateProcessCraftEntities = new ArrayList<>();
                            //查询工艺工序路线是否存在两个五轴加工中心
                            //boolean flag = false;
                            //转换为工序名list处理
//                            List<String> craftNameList = connectCraftEntities
//                                    .stream()
//                                    .map(ProcessCraftEntity::getName)
//                                    .collect(Collectors.toList());
//                            if (Collections.frequency(craftNameList, CONNECT_CRAFT_NAME4) == 2) {
//                                flag = true;
//                            }

                            //判断备注字段是否存在排序
                            //判断备注字段是否存在排序
                            Boolean flag = false;
                            QueryWrapper<SubProgramEntity> subWrapper = new QueryWrapper<>();
                            subWrapper.eq("program_code" , connectProgram.getCode());
                            List<SubProgramEntity> subProgramEntityList = subProgramMapper.selectList(subWrapper);
                            if(CollectionUtil.isNotEmpty(subProgramEntityList)) {
                                List<Integer> versionList = subProgramEntityList.stream().map(SubProgramEntity::getVersion).collect(Collectors.toList());
                                if (CollectionUtil.isNotEmpty(versionList)) {
                                    List<Integer> versions = versionList
                                            .stream()
                                            .distinct()
                                            .sorted()
                                            .collect(Collectors.toList());
                                    if(versions.size()>2 && versions.contains(2)){
                                        flag = true;
                                    }
                                }
                            }
                            if(flag){
                                splitAndConnect(connectProgram, connectCraftEntities, updateProcessCraftEntities);
                            }else {
                                notSplitAndConnect(connectProgram, connectCraftEntities, updateProcessCraftEntities);
                            }


                            //设置工序和程序的关联关系
                            if(CollectionUtil.isNotEmpty(updateProcessCraftEntities)){
                                processCraftMapper.updateBatchById(updateProcessCraftEntities);
                                connectProcess.setStatus(1);
                                //设置产品的状态为已完成，推送工单快照数据
                                productionEntity.setProcessStatus(1);
                                productionEntity.setStatus(1);
                                if (!CollectionUtil.isEmpty(connectOrders)) {
                                    connectOrders.forEach(orderEntity -> {
                                        if (orderEntity.getStatus()<=CommonConstant.PRODUCTION_PROCESS_CONNECT) {
                                            //设置工单完成状态以及推送快照数据
                                            orderEntity.setStatus(2);
                                            //TO DO 后续物料bom信息也需要同步
                                            OrderDo orderDo = new OrderDo(orderEntity, connectCraftEntities, connectBom);
                                            // 持久化快照
                                            orderManageService.persistOrder(orderDo);
                                        }
                                        if(orderEntity.getStatus() == 3){
                                            orderEntity.setStatus(2);
                                        }
                                        updateOrderList.add(orderEntity);
                                    });
                                }
                            }
                        }
                    }else{
                        if (!CollectionUtil.isEmpty(connectOrders) && CollectionUtil.isNotEmpty(connectCraftEntities)) {
                            connectOrders.forEach(orderEntity -> {
                                if (orderEntity.getStatus()<CommonConstant.ORDER_PRODUCTION_CONNECT_DONE) {
                                    //设置工单完成状态以及推送快照数据
                                    orderEntity.setStatus(3);
                                    //TO DO 后续物料bom信息也需要同步
                                    OrderDo orderDo = new OrderDo(orderEntity, connectCraftEntities, connectBom);
                                    // 持久化快照
                                    orderManageService.persistOrder(orderDo);
                                }
                                updateOrderList.add(orderEntity);
                            });
                        }
                    }
                    productionEntity.setProcessStatus(connectProcess.getStatus());
                    updateProcessConnectList.add(connectProcess);
                }
            });

        }
        //持久化
        if(CollectionUtil.isNotEmpty(updateOrderList)){
            orderMapper.updateBatchById(updateOrderList);
        }
        if(CollectionUtil.isNotEmpty(addProductionProcessConnect)){
            productionProcessMapper.insertBatchSomeColumn(addProductionProcessConnect);
        }
        if(CollectionUtil.isNotEmpty(productionEntities)){
            productionMapper.updateBatchById(productionEntities);
        }
        if(CollectionUtil.isNotEmpty(updateProcessConnectList)){
            processMapper.updateBatchById(updateProcessConnectList);
        }
    }

    private static void notSplitAndConnect(ProgramEntity connectProgram, List<ProcessCraftEntity> connectCraftEntities, List<ProcessCraftEntity> updateProcessCraftEntities) {
        connectCraftEntities.forEach(
                processCraftEntity -> {
                    keyWordList.forEach(s -> {
                         if (processCraftEntity.getName().contains(s)) {
                            processCraftEntity.setProgramCode(connectProgram.getCode());
                            processCraftEntity.setConnectSubprogramVersion(1);
                            updateProcessCraftEntities.add(processCraftEntity);
                        }
                    });
                }
        );
    }

    private static void splitAndConnect(ProgramEntity connectProgram, List<ProcessCraftEntity> connectCraftEntities, List<ProcessCraftEntity> updateProcessCraftEntities) {
        Integer version = CommonConstant.INIT_VERSION;
        for (ProcessCraftEntity connectCraftEntity : connectCraftEntities) {
            //判断工序名如果在list里面 且是第一个工序名为五轴加工中心（五轴加工中心关联后 如果还有）
            if(keyWordList.contains(connectCraftEntity.getName()) && (version != 2 || !Objects.equals(connectCraftEntity.getName(), CONNECT_CRAFT_NAME4))){
                connectCraftEntity.setProgramCode(connectProgram.getCode());
                connectCraftEntity.setConnectSubprogramVersion(1);
                updateProcessCraftEntities.add(connectCraftEntity);
                if(connectCraftEntity.getName().equals(CONNECT_CRAFT_NAME4)){
                    version += 1;
                }
            } else if (Objects.equals(connectCraftEntity.getName(), CONNECT_CRAFT_NAME4) && version == 2) {
                connectCraftEntity.setProgramCode(connectProgram.getCode());
                connectCraftEntity.setConnectSubprogramVersion(version);
                updateProcessCraftEntities.add(connectCraftEntity);
            }
        }
    }

    @DSTransactional
    public Boolean abutmentEntryExitRecord(String startTime , String endTime){
        //querySqlServerService
//        String post = HttpUtil.post("", new HashMap<>());
        List<AbutmentEntryExitRecordEntity> existRecords = abutmentEntryAndExitMapper.selectList(new QueryWrapper<>());
        //List<String> existDocumentNumbers = existRecords.stream().map(AbutmentEntryExitRecordEntity::getDocumentNumber).collect(Collectors.toList());
        List<AbutmentEntryExitRecordEntity> abutmentEntryExitRecordEntities = querySqlServerService.queryAbutmentEntryExitRecord(startTime , endTime);
        if(CollectionUtil.isNotEmpty(abutmentEntryExitRecordEntities)){
            //过滤新增数据
            List<AbutmentEntryExitRecordEntity> insertList = abutmentEntryExitRecordEntities.stream().filter(abutmentEntryExitRecordEntity -> !existRecords.contains(abutmentEntryExitRecordEntity)).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(insertList)){
                abutmentEntryAndExitMapper.insertBatchSomeColumn(abutmentEntryExitRecordEntities);
            }
            //过滤修改数据
            List<AbutmentEntryExitRecordEntity> updateList = abutmentEntryExitRecordEntities.stream().filter(existRecords::contains).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(updateList)){
                existRecords.forEach(abutmentEntryExitRecordEntity ->
                        updateList.forEach(updateAbutmentEntryExitRecordEntity -> {
                            if(abutmentEntryExitRecordEntity.getDocumentNumber() == updateAbutmentEntryExitRecordEntity.getDocumentNumber()){
                                updateAbutmentEntryExitRecordEntity.setId(abutmentEntryExitRecordEntity.getId());
                            }
                        }));
                abutmentEntryAndExitMapper.updateBatchById(updateList);
            }
        }
        return Boolean.TRUE;
    }

    public List<AbutmentEntryExitRecordEntity> queryAbutmentRecords(){
        return abutmentEntryAndExitMapper.selectList(new QueryWrapper<>());
    }


    public void exportAbutmentInboundRecords(HttpServletResponse response, Integer monthIndex) throws IOException {
        Map<String, String> monthTimeRange = CommonUtil.getMonthTimeRange(monthIndex);
        //设置excel文件的mime类型
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        List<AbutmentEntryExitRecordEntity> inboundRecords = abutmentEntryExitRepository.getInboundRecords(monthTimeRange.getOrDefault("startTime" , "") , monthTimeRange.getOrDefault("endTime" , "") , INBOUND_TYPE);
        List<AbutmentInboundExport> exportInboundRecords = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(inboundRecords)){
            exportInboundRecords = inboundRecords.stream().map(this::transferInboundExport).collect(Collectors.toList());
        }
        Integer month = monthIndex + 1;
        String fileName = month +"月份入库记录";
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName+".xlsx" ,"UTF-8" ));
        EasyExcel.write(response.getOutputStream(), AbutmentInboundExport.class)
                .sheet(fileName)
                .registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/
                .registerWriteHandler(new CustomCellWriteHeightConfig()) /*自适应行高（根据自己情况选择使用，我这里没用到）*/
                .registerWriteHandler(ExcelUtil.getStyleStrategy())/*引用样式*/
                .doWrite(exportInboundRecords);
    }

    private AbutmentInboundExport transferInboundExport(AbutmentEntryExitRecordEntity abutmentEntryExitRecordEntity) {
        AbutmentInboundExport abutmentInboundExport = new AbutmentInboundExport();
        BeanUtil.copyProperties(abutmentEntryExitRecordEntity , abutmentInboundExport);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        abutmentInboundExport.setOperateTime(sdf.format(new Date(abutmentInboundExport.getOperateTime())));
        abutmentInboundExport.setCreateTime(sdf.format(new Date(abutmentInboundExport.getCreateTime())));
        return abutmentInboundExport;
    }

    public void exportAbutmentOutboundRecords(HttpServletResponse response, Integer monthIndex) throws IOException {
        Map<String, String> monthTimeRange = CommonUtil.getMonthTimeRange(monthIndex);
        //设置excel文件的mime类型
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        List<AbutmentEntryExitRecordEntity> inboundRecords = abutmentEntryExitRepository.getInboundRecords(monthTimeRange.getOrDefault("startTime" , "") , monthTimeRange.getOrDefault("endTime" , "") , OUTBOUND_TYPE);
        List<AbutmentOutboundExport> exportOutboundRecords = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(inboundRecords)){
            exportOutboundRecords = inboundRecords.stream().map(this::transferOutboundExport).collect(Collectors.toList());
        }
        Integer month = monthIndex+1;
        String fileName = month +"月份出库记录";
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName+".xlsx" ,"UTF-8" ));
        EasyExcel.write(response.getOutputStream(), AbutmentOutboundExport.class)
                .sheet(fileName)
                .registerWriteHandler(new CustomCellWriteWidthConfig()) /*自适应列宽*/
                .registerWriteHandler(new CustomCellWriteHeightConfig()) /*自适应行高（根据自己情况选择使用，我这里没用到）*/
                .registerWriteHandler(ExcelUtil.getStyleStrategy())
                .doWrite(exportOutboundRecords);
    }

    private AbutmentOutboundExport transferOutboundExport(AbutmentEntryExitRecordEntity abutmentEntryExitRecordEntity) {
        AbutmentOutboundExport abutmentOutboundExport = new AbutmentOutboundExport();
        BeanUtil.copyProperties(abutmentEntryExitRecordEntity , abutmentOutboundExport);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        abutmentOutboundExport.setOperateTime(sdf.format(new Date(abutmentOutboundExport.getOperateTime())));
        abutmentOutboundExport.setCreateTime(sdf.format(new Date(abutmentOutboundExport.getCreateTime())));
        return abutmentOutboundExport;
    }

    public List<String> abutmentDataReload(List<String> taskIds) {
        List<Map<String , String>> materialNos = orderManageService.abutmentOrder(taskIds);
        if(CollectionUtil.isEmpty(materialNos)){
            return new ArrayList<>();
        }
        productionManageService.abutmentProductionReload1(materialNos);
        subProgramManageService.abutmentSubProgramReload1(materialNos);
        List<String> partnoList = new ArrayList<>();
        materialNos.forEach(stringStringMap -> {
            partnoList.add(stringStringMap.get("materialNo"));
        });
        return partnoList;
    }


    public Object abutmentEntryExit(String startTime, String endTime) throws ToolLifeCycleException {
        List<AbutmentEntryExitRecordEntity> abutmentEntryExitRecordEntities = querySqlServerService.queryAbutmentEntryExitRecord(startTime , endTime);
        //处理仓库库位id
        if(CollectionUtil.isNotEmpty(abutmentEntryExitRecordEntities)){
            abutmentEntryExitRecordEntities = abutmentEntryExitRecordEntities
                    .stream()
                    .filter(abutmentEntryExitRecordEntity -> abutmentEntryExitRecordEntity.getType() == 1)
                    .collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(abutmentEntryExitRecordEntities)){
                for (AbutmentEntryExitRecordEntity abutmentEntryExitRecordEntity : abutmentEntryExitRecordEntities) {
                    if(ObjectUtil.isNotNull(abutmentEntryExitRecordEntity.getStorageLocation())){
                        continue;
                    }
                    Integer warehouseId = warehouseRespository.selectWarehouseId(abutmentEntryExitRecordEntity.getStorageLocation().substring(0,1)+"货架");
                    List<AbutmentStockVo> abutmentStockVos = abutmentEntryExitRepository.selectLocationId(abutmentEntryExitRecordEntity.getPartno() , warehouseId);
                    abutmentStockVos = allocateNumber(abutmentStockVos , abutmentEntryExitRecordEntity.getNumber());
                    if (abutmentStockVos.isEmpty()) {
                        throw new ToolLifeCycleException(ToolLifeCycleEx.INBOUND_OR_OUTBOUND_NUMBER_EXCEED.getCode(), ToolLifeCycleEx.INBOUND_OR_OUTBOUND_NUMBER_EXCEED.getMsg());
                    }
                    //调用零件出库接口
                    for (AbutmentStockVo abutmentStockVo : abutmentStockVos) {
                        InBoundOrOutBoundTimeReq inBoundOrOutBoundTimeReq = new InBoundOrOutBoundTimeReq();
                        inBoundOrOutBoundTimeReq.setPartno(abutmentEntryExitRecordEntity.getPartno());
                        inBoundOrOutBoundTimeReq.setBz(abutmentEntryExitRecordEntity.getBz());
                        inBoundOrOutBoundTimeReq.setCreateTime(abutmentEntryExitRecordEntity.getCreateTime());
                        inBoundOrOutBoundTimeReq.setOperator(abutmentEntryExitRecordEntity.getOperator());
                        inBoundOrOutBoundTimeReq.setNumber(abutmentStockVo.getNumber());
                        inBoundOrOutBoundTimeReq.setInventoryLocationId(abutmentStockVo.getLocationId());
                        inBoundOrOutBoundTimeReq.setTaskId(abutmentEntryExitRecordEntity.getTaskId());
                        inventoryLocationService.outboundLocationTool(inBoundOrOutBoundTimeReq);
                    }
                }
            }
        }
        return Boolean.TRUE;
    }

    private List<AbutmentStockVo> allocateNumber(List<AbutmentStockVo> abutmentStockVos, Integer number) {
        if(CollectionUtil.isEmpty(abutmentStockVos)){
            //无库存
            return abutmentStockVos;
        }
        if(abutmentStockVos.stream().mapToInt(AbutmentStockVo::getNumber).sum() <= number){
            //库存数量不足
            return new ArrayList<>();
        }
        List<AbutmentStockVo> allocateList = new ArrayList<>();
        for (AbutmentStockVo abutmentStockVo : abutmentStockVos) {
            //按数量分配库位
            if(number > abutmentStockVo.getNumber()){
                AbutmentStockVo abutmentStockVo1 = new AbutmentStockVo();
                BeanUtil.copyProperties(abutmentStockVo  , abutmentStockVo1);
                allocateList.add(abutmentStockVo1);
                number = number - abutmentStockVo.getNumber();
                continue;
            }
            AbutmentStockVo abutmentStockVo1 = new AbutmentStockVo();
            abutmentStockVo1.setLocationId(abutmentStockVo.getLocationId());
            abutmentStockVo1.setNumber(number);
            allocateList.add(abutmentStockVo1);
            break;
        }
        return allocateList;
    }

    public Object importFirstCabinetOutbound(List<FirstCabinetOutboundImport> importData) {
        if(CollectionUtil.isEmpty(importData)){
            return Boolean.TRUE;
        }
        importData.forEach(firstCabinetOutboundImport -> {
            Integer number = -firstCabinetOutboundImport.getNumber();
            QueryWrapper<ToolForkInfoEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("partno" , firstCabinetOutboundImport.getPartno());
            ToolForkInfoEntity toolForkInfoEntity = toolForkInfoMapper.selectOne(wrapper);
            if(ObjectUtil.isNull(toolForkInfoEntity)){
                return;
            }
            //查询该刀具在我们系统中的库存情况
            List<LocationNumberVo> locationNumberVos = warehouseRespository.queryFirstStockByToolId(toolForkInfoEntity.getId());
            if(CollectionUtil.isNotEmpty(locationNumberVos)){
                //校验数量
                int existStock = locationNumberVos.stream().mapToInt(LocationNumberVo::getNumber).sum();
                if(existStock < number){
                    return;
                }
                List<LocationNumberVo> outLocationNumberVos = inventoryTask.findLocationNumber(locationNumberVos, number);
                //处理时间
                String date = firstCabinetOutboundImport.getDate();
                String[] split = date.split("\\/");
                String entryTime = firstCabinetOutboundImport.getEntryTime();
                String[] entryTimeSplit = entryTime.split(":");
                //出库刀具
                if(CollectionUtil.isNotEmpty(outLocationNumberVos)){
                    outLocationNumberVos.forEach(locationNumberVo -> {
                        InBoundOrOutBoundTimeReq inBoundOrOutBoundReq = new InBoundOrOutBoundTimeReq();
                        inBoundOrOutBoundReq.setNumber(locationNumberVo.getNumber());
                        inBoundOrOutBoundReq.setBz("");
                        inBoundOrOutBoundReq.setInventoryLocationId(locationNumberVo.getId());
                        inBoundOrOutBoundReq.setOperator(firstCabinetOutboundImport.getOperator());
                        inBoundOrOutBoundReq.setPartno(firstCabinetOutboundImport.getPartno());
                        inBoundOrOutBoundReq.setCreateTime(CommonUtil.getDate(Integer.parseInt(split[0]),//年
                                Integer.parseInt(split[1]),//月
                                        Integer.parseInt(split[2]),//日
                                                Integer.parseInt(entryTimeSplit[0]),//时
                                                        Integer.parseInt(entryTimeSplit[1]),//分
                                                                Integer.parseInt(entryTimeSplit[2].substring(0,2))));
                        inBoundOrOutBoundReq.setPartType(toolForkInfoEntity.getPartType());
                        try {
                                inventoryLocationService.outboundLocationTool(inBoundOrOutBoundReq);
                        } catch (ToolLifeCycleException e) {
                            log.error("sync icabinet stock error =>{}" + e.getMsg() + new Date());
                        }
                    });
                }
            }
        });
        return Boolean.TRUE;
    }

    public Object importFirstCabinetStock(List<FirstCabinetStockImport> importData , String operator) {
        if(CollectionUtil.isNotEmpty(importData)){
            List<ImportToolForkInfoVo> importToolForkInfoVos = importData
                    .stream()
                    .map(this::transferImportForkVo)
                    .collect(Collectors.toList());
            inventoryLocationService.insertPartnosReload1(importToolForkInfoVos);
            //查询所有一级库货架的allType库位id
            List<Integer> locationIds = inventoryLocationRespository.selectAllTypeLocationIds(WarehouseConstant.FIRST_TOOL_CABINET);
            importData = importData
                    .stream()
                    .filter(firstCabinetStockImport -> ObjectUtil.isNotNull(firstCabinetStockImport.getPartno()))
                    .collect(Collectors.toList());

            importData.forEach(firstCabinetStockImport -> {
                InBoundOrOutBoundTimeReq inBoundOrOutBoundReq = new InBoundOrOutBoundTimeReq();
                inBoundOrOutBoundReq.setNumber(firstCabinetStockImport.getNumber());
                inBoundOrOutBoundReq.setBz("");
                //查询入库库位
                Integer locationId = findLocationId(firstCabinetStockImport.getPartno());
                if(ObjectUtil.isNull(locationId) || (ObjectUtil.isNotNull(locationId) && locationId ==0)){
                    Random random = new Random();
                    int index = random.nextInt(locationIds.size());
                    locationId = locationIds.get(index);
                }
                inBoundOrOutBoundReq.setInventoryLocationId(locationId);
                inBoundOrOutBoundReq.setOperator(operator);
                inBoundOrOutBoundReq.setPartno(firstCabinetStockImport.getPartno());
                inBoundOrOutBoundReq.setCreateTime(new Date());
                inBoundOrOutBoundReq.setPartType(firstCabinetStockImport.getPartType());
                try {
                    inventoryLocationService.inboundLocationTool(inBoundOrOutBoundReq);
                } catch (ToolLifeCycleException e) {
                    log.error("sync icabinet stock error =>{}" + e.getMsg() + new Date());
                }
            });
        }
        return null;
    }

    private ImportToolForkInfoVo transferImportForkVo(FirstCabinetStockImport firstCabinetStockImport) {
        ImportToolForkInfoVo importToolForkInfoVo = new ImportToolForkInfoVo();
        importToolForkInfoVo.setIdnr(firstCabinetStockImport.getPartType());
        importToolForkInfoVo.setPartno(firstCabinetStockImport.getPartno());
        return importToolForkInfoVo;
    }

    private Integer findLocationId(String partno){
        QueryWrapper<ToolConnectEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("partno" , partno);
        List<ToolConnectEntity> toolConnectEntities = toolConnectMapper.selectList(wrapper);
        if(CollectionUtil.isNotEmpty(toolConnectEntities)){
            toolConnectEntities = toolConnectEntities.stream().filter(toolConnectEntity -> StringUtils.isNotBlank(toolConnectEntity.getLocationNum())).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(toolConnectEntities)){
                ToolConnectEntity toolConnectEntity = toolConnectEntities.get(0);
                String locationNum = toolConnectEntity.getLocationNum();
                String location = toolConnectEntity.getLocationNum().substring(1);
                String[] split = location.split("-");
                return inventoryLocationRespository
                        .selectByCondition(split[0] , split[1] , locationNum.substring(0 ,1) + "货架");
            }
        }
        return 0;
    }

    public void deleteData(List<String> taskIds) {
        List<AbutmentOrderEntity> abutmentOrders = querySqlServerService.abutmentOrder(taskIds);
        orderManageService.deleteData(abutmentOrders);
        //deleteData(abutmentOrders);
    }
}
